Вход

Просмотр полной версии : фишка или баг querySelectorAll?


PeaceCoder
09.10.2011, 13:48
Вот решил тестануть а верно ли работает нативный метод querySelectorAll в браузере Firefox.

<html>
<body>
<span>
<div id='abc'>
<i class='abc123'>текст</i>
<span><i class='abc345'></i></span>
</div>
<i class='cde'></i>
</span>
<script type='text/javascript'>
A=document.getElementById('abc');
B= A.querySelectorAll('span i'); // тут должен быть массив из элемента .class=abc345, т.к. выборка идет из элемента, а не из документа.
alert([B[0].className,B.length]); // но это не так
C = document.querySelectorAll('#abc span i');
alert(C.length==1); // а тут верно

D = A.querySelectorAll('#abc span i');
alert([D[0].className, D.length]); // А теперь верно. Это как понимать? выборка из элемента равносильна выборки из документа?

E = A.querySelectorAll.call(A,'span i');
alert([E[0].className, E.length]); //и так не работает
</script>
</body>
</html>


В хроме тот же баг.

walik
09.10.2011, 14:06
Предположу что все же так задумано, потому что если i вынести из дивки то он не будет найден.

Even though the method is invoked on an element, selectors are still evaluated in the context of the entire document.
Хотя метод вызывается элементом, селекторы по-прежнему оценивается в контексте всего документа.
http://www.w3.org/TR/selectors-api/

B= A.querySelectorAll('span i'); // тут должен быть массив из элемента .class=abc345, т.к. выборка идет из элемента, а не из документа.
Логика у querySelectorAll я как понимаю такова:
Вы в конечном итоге хотите получить элементы i, но вы еще указали что у этих элементов должен быть родитель спан, а так же они должны являтся потомками элемента в котором ищите (в данном случае это A).
Элемент с классом "abc345" будет найден так как он является потомком элемента span и потомком элемента в котором ищем.
А элемент с классом "abc123" тоже будет найден (хотя вы ожидаете что его быть не должно) так как он тоже подходит под условия. Он является потомком элемента в котором ищем, а так же у него один из родителей есть span (Читай выше что селекторы оцениваются в конексте всего документа)

PeaceCoder
09.10.2011, 14:16
Хотя метод вызывается элементом, селекторы по-прежнему оценивается в контексте всего документа.
и это логически не верно. я считаю это багом
Логика у querySelectorAll я как понимаю такова:
Да так оно и есть. Добавив еще 1 тестовый элемент это можно увидеть по результатам выборок

walik
09.10.2011, 14:25
Вот такие же примеры:

<!DOCTYPE HTML>
<html>
<body>
<div id='abc'>
<span class="my"></span>
</div>
<script type='text/javascript'>
A=document.getElementById('abc');
B= A.querySelectorAll('span');
alert(B[0].className); // Наш спан будет найден как и надо
B= A.querySelectorAll('body span'); // Тут вроде не должен быть найдет, у дивки же нету тега body, но все равно найден, так как поиск все равно учитывает весь документ
alert(B[0].className);
// И так далее тоже все будет найдено
B= A.querySelectorAll('body div span');
B= A.querySelectorAll('div span');
B= A.querySelectorAll('#abc span');
</script>
</body>
</html>


и это логически не верно. я считаю это багом
Можно считать и багом, но может у такого подхода есть и плюсы, мы можем указывать поиск по всему документу, но найдены будут все равно только те которые являются потомками нашего элемента от которого мы ищем.

Но с другой стороны это нельзя считать багом, так как баг это ошибки допущенные разработчиками, а в данном случае это так и задумано :)

PeaceCoder
09.10.2011, 14:33
являются потомками нашего элемента от которого мы ищем.
А какой смысл указывать дополнительные фильтры если они могут быть и в контексте элемента и вне его контекста?
Другими словами: какой смысл делать выборку из элемента?

walik
09.10.2011, 14:41
Другими словами: какой смысл делать выборку из элемента?
Смысл в том что в результат попадут все равно только те которые являются потомками.
Ну а вообще я тоже придерживаюсь мнения что как то не правильно, или может не до понимаю чего то :)

Может разработчики видят в этом какую ту изюминку в этом, но я не могу представить себе случая где необходимо искать во всем документе, а получат только потомков.

B@rmaley.e><e
09.10.2011, 14:46
и это логически не верно. я считаю это багомТакова спецификация. Во второй версии Selectors API вводится queryScopedSelectorAll, который, возможно, решит проблему (я не совсем понял его отличия от обычного querySelectorAll).

PeaceCoder
09.10.2011, 17:09
ну посмотрим че там будет во второй спецификации. главное что это недоразумение легко исправить.